package org.xbill.DNS;

import java.io.PrintStream;
import java.util.Date;
import org.xbill.DNS.utils.HMAC;
import org.xbill.DNS.utils.base64;

public class TSIG
{
  public static final short FUDGE = 300;
  public static final Name HMAC;
  public static final Name HMAC_MD5 = Name.fromConstantString("HMAC-MD5.SIG-ALG.REG.INT.");
  private static final String HMAC_MD5_STR = "HMAC-MD5.SIG-ALG.REG.INT.";
  public static final Name HMAC_SHA1;
  private static final String HMAC_SHA1_STR = "hmac-sha1.";
  public static final Name HMAC_SHA256;
  private static final String HMAC_SHA256_STR = "hmac-sha256.";
  private Name alg;
  private String digest;
  private byte[] key;
  private Name name;

  static
  {
    HMAC = HMAC_MD5;
    HMAC_SHA1 = Name.fromConstantString("hmac-sha1.");
    HMAC_SHA256 = Name.fromConstantString("hmac-sha256.");
  }

  public TSIG(String paramString1, String paramString2)
  {
    this(HMAC_MD5, paramString1, paramString2);
  }

  public TSIG(String paramString1, String paramString2, String paramString3)
  {
    this(HMAC_MD5, paramString2, paramString3);
    if (paramString1.equalsIgnoreCase("hmac-md5"))
      this.alg = HMAC_MD5;
    while (true)
    {
      while (true)
      {
        getDigest();
        return;
        if (!(paramString1.equalsIgnoreCase("hmac-sha1")))
          break;
        this.alg = HMAC_SHA1;
      }
      if (!(paramString1.equalsIgnoreCase("hmac-sha256")))
        break;
      this.alg = HMAC_SHA256;
    }
    throw new IllegalArgumentException("Invalid TSIG algorithm");
  }

  public TSIG(Name paramName, String paramString1, String paramString2)
  {
    this.key = base64.fromString(paramString2);
    if (this.key == null)
      throw new IllegalArgumentException("Invalid TSIG key string");
    try
    {
      this.name = Name.fromString(paramString1, Name.root);
      this.alg = paramName;
      getDigest();
      return;
    }
    catch (TextParseException localTextParseException)
    {
      throw new IllegalArgumentException("Invalid TSIG key name");
    }
  }

  public TSIG(Name paramName1, Name paramName2, byte[] paramArrayOfByte)
  {
    this.name = paramName2;
    this.alg = paramName1;
    this.key = paramArrayOfByte;
    getDigest();
  }

  public TSIG(Name paramName, byte[] paramArrayOfByte)
  {
    this(HMAC_MD5, paramName, paramArrayOfByte);
  }

  public static TSIG fromString(String paramString)
  {
    TSIG localTSIG;
    String[] arrayOfString = paramString.split("[:/]");
    if ((arrayOfString.length < 2) || (arrayOfString.length > 3))
      throw new IllegalArgumentException("Invalid TSIG key specification");
    if (arrayOfString.length == 3)
      localTSIG = new TSIG(arrayOfString[0], arrayOfString[1], arrayOfString[2]);
    while (true)
    {
      return localTSIG;
      localTSIG = new TSIG(HMAC_MD5, arrayOfString[0], arrayOfString[1]);
    }
  }

  private void getDigest()
  {
    if (this.alg.equals(HMAC_MD5))
      this.digest = "md5";
    while (true)
    {
      while (true)
      {
        return;
        if (!(this.alg.equals(HMAC_SHA1)))
          break;
        this.digest = "sha-1";
      }
      if (!(this.alg.equals(HMAC_SHA256)))
        break;
      this.digest = "sha-256";
    }
    throw new IllegalArgumentException("Invalid algorithm");
  }

  public void apply(Message paramMessage, int paramInt, TSIGRecord paramTSIGRecord)
  {
    paramMessage.addRecord(generate(paramMessage, paramMessage.toWire(), paramInt, paramTSIGRecord), 3);
    paramMessage.tsigState = 3;
  }

  public void apply(Message paramMessage, TSIGRecord paramTSIGRecord)
  {
    apply(paramMessage, 0, paramTSIGRecord);
  }

  public void applyStream(Message paramMessage, TSIGRecord paramTSIGRecord, boolean paramBoolean)
  {
    if (paramBoolean)
      apply(paramMessage, paramTSIGRecord);
    while (true)
    {
      return;
      Date localDate = new Date();
      HMAC localHMAC = new HMAC(this.digest, this.key);
      int i = Options.intValue("tsigfudge");
      if ((i < 0) || (i > 32767))
        i = 300;
      DNSOutput localDNSOutput1 = new DNSOutput();
      localDNSOutput1.writeU16(paramTSIGRecord.getSignature().length);
      localHMAC.update(localDNSOutput1.toByteArray());
      localHMAC.update(paramTSIGRecord.getSignature());
      localHMAC.update(paramMessage.toWire());
      DNSOutput localDNSOutput2 = new DNSOutput();
      long l1 = localDate.getTime() / 1000L;
      int j = (int)(l1 >> 32);
      long l2 = l1 & 0xFFFFFFFF;
      localDNSOutput2.writeU16(j);
      localDNSOutput2.writeU32(l2);
      localDNSOutput2.writeU16(i);
      localHMAC.update(localDNSOutput2.toByteArray());
      byte[] arrayOfByte1 = localHMAC.sign();
      byte[] arrayOfByte2 = (byte[])null;
      paramMessage.addRecord(new TSIGRecord(this.name, 255, 0L, this.alg, localDate, i, arrayOfByte1, paramMessage.getHeader().getID(), 0, arrayOfByte2), 3);
      paramMessage.tsigState = 3;
    }
  }

  public TSIGRecord generate(Message paramMessage, byte[] paramArrayOfByte, int paramInt, TSIGRecord paramTSIGRecord)
  {
    Date localDate;
    int i;
    byte[] arrayOfByte1;
    if (paramInt != 18)
    {
      localDate = new Date();
      HMAC localHMAC = null;
      if ((paramInt == 0) || (paramInt == 18))
        localHMAC = new HMAC(this.digest, this.key);
      i = Options.intValue("tsigfudge");
      if ((i < 0) || (i > 32767))
        i = 300;
      if (paramTSIGRecord != null)
      {
        DNSOutput localDNSOutput1 = new DNSOutput();
        localDNSOutput1.writeU16(paramTSIGRecord.getSignature().length);
        if (localHMAC != null)
        {
          localHMAC.update(localDNSOutput1.toByteArray());
          localHMAC.update(paramTSIGRecord.getSignature());
        }
      }
      if (localHMAC != null)
        localHMAC.update(paramArrayOfByte);
      DNSOutput localDNSOutput2 = new DNSOutput();
      this.name.toWireCanonical(localDNSOutput2);
      localDNSOutput2.writeU16(255);
      localDNSOutput2.writeU32(0L);
      this.alg.toWireCanonical(localDNSOutput2);
      long l1 = localDate.getTime() / 1000L;
      int j = (int)(l1 >> 32);
      long l2 = l1 & 0xFFFFFFFF;
      localDNSOutput2.writeU16(j);
      localDNSOutput2.writeU32(l2);
      localDNSOutput2.writeU16(i);
      localDNSOutput2.writeU16(paramInt);
      localDNSOutput2.writeU16(0);
      if (localHMAC != null)
        localHMAC.update(localDNSOutput2.toByteArray());
      if (localHMAC == null)
        break label379;
      arrayOfByte1 = localHMAC.sign();
    }
    while (true)
    {
      while (true)
      {
        byte[] arrayOfByte2 = (byte[])null;
        if (paramInt == 18)
        {
          DNSOutput localDNSOutput3 = new DNSOutput();
          long l3 = new Date().getTime() / 1000L;
          int k = (int)(l3 >> 32);
          long l4 = l3 & 0xFFFFFFFF;
          localDNSOutput3.writeU16(k);
          localDNSOutput3.writeU32(l4);
          arrayOfByte2 = localDNSOutput3.toByteArray();
        }
        return new TSIGRecord(this.name, 255, 0L, this.alg, localDate, i, arrayOfByte1, paramMessage.getHeader().getID(), paramInt, arrayOfByte2);
        localDate = paramTSIGRecord.getTimeSigned();
      }
      label379: arrayOfByte1 = new byte[0];
    }
  }

  public int recordLength()
  {
    return (8 + 4 + 18 + 8 + 10 + this.name.length() + this.alg.length());
  }

  public byte verify(Message paramMessage, byte[] paramArrayOfByte, int paramInt, TSIGRecord paramTSIGRecord)
  {
    int i;
    paramMessage.tsigState = 4;
    TSIGRecord localTSIGRecord = paramMessage.getTSIG();
    HMAC localHMAC = new HMAC(this.digest, this.key);
    if (localTSIGRecord == null)
      i = 1;
    while (true)
    {
      while (true)
      {
        while (true)
        {
          return i;
          if ((localTSIGRecord.getName().equals(this.name)) && (localTSIGRecord.getAlgorithm().equals(this.alg)))
            break;
          if (Options.check("verbose"))
            System.err.println("BADKEY failure");
          i = 17;
        }
        long l1 = System.currentTimeMillis();
        long l2 = localTSIGRecord.getTimeSigned().getTime();
        long l3 = localTSIGRecord.getFudge();
        if (Math.abs(l1 - l2) <= 1000L * l3)
          break;
        if (Options.check("verbose"))
          System.err.println("BADTIME failure");
        i = 18;
      }
      if ((paramTSIGRecord != null) && (localTSIGRecord.getError() != 17) && (localTSIGRecord.getError() != 16))
      {
        DNSOutput localDNSOutput2 = new DNSOutput();
        localDNSOutput2.writeU16(paramTSIGRecord.getSignature().length);
        localHMAC.update(localDNSOutput2.toByteArray());
        localHMAC.update(paramTSIGRecord.getSignature());
      }
      paramMessage.getHeader().decCount(3);
      byte[] arrayOfByte = paramMessage.getHeader().toWire();
      paramMessage.getHeader().incCount(3);
      localHMAC.update(arrayOfByte);
      int j = paramMessage.tsigstart - arrayOfByte.length;
      localHMAC.update(paramArrayOfByte, arrayOfByte.length, j);
      DNSOutput localDNSOutput1 = new DNSOutput();
      localTSIGRecord.getName().toWireCanonical(localDNSOutput1);
      localDNSOutput1.writeU16(localTSIGRecord.dclass);
      localDNSOutput1.writeU32(localTSIGRecord.ttl);
      localTSIGRecord.getAlgorithm().toWireCanonical(localDNSOutput1);
      long l4 = localTSIGRecord.getTimeSigned().getTime() / 1000L;
      int k = (int)(l4 >> 32);
      long l5 = l4 & 0xFFFFFFFF;
      localDNSOutput1.writeU16(k);
      localDNSOutput1.writeU32(l5);
      localDNSOutput1.writeU16(localTSIGRecord.getFudge());
      localDNSOutput1.writeU16(localTSIGRecord.getError());
      if (localTSIGRecord.getOther() != null)
      {
        localDNSOutput1.writeU16(localTSIGRecord.getOther().length);
        localDNSOutput1.writeByteArray(localTSIGRecord.getOther());
      }
      while (true)
      {
        while (true)
        {
          localHMAC.update(localDNSOutput1.toByteArray());
          if (!(localHMAC.verify(localTSIGRecord.getSignature())))
            break label461;
          paramMessage.tsigState = 1;
          i = 0;
        }
        localDNSOutput1.writeU16(0);
      }
      if (Options.check("verbose"))
        label461: System.err.println("BADSIG failure");
      i = 16;
    }
  }

  public int verify(Message paramMessage, byte[] paramArrayOfByte, TSIGRecord paramTSIGRecord)
  {
    return verify(paramMessage, paramArrayOfByte, paramArrayOfByte.length, paramTSIGRecord);
  }

  public static class StreamVerifier
  {
    private TSIG key;
    private TSIGRecord lastTSIG;
    private int lastsigned;
    private int nresponses;
    private HMAC verifier;

    public StreamVerifier(TSIG paramTSIG, TSIGRecord paramTSIGRecord)
    {
      this.key = paramTSIG;
      this.verifier = new HMAC(TSIG.access$0(this.key), TSIG.access$1(this.key));
      this.nresponses = 0;
      this.lastTSIG = paramTSIGRecord;
    }

    public int verify(Message paramMessage, byte[] paramArrayOfByte)
    {
      int k;
      TSIGRecord localTSIGRecord = paramMessage.getTSIG();
      this.nresponses = (1 + this.nresponses);
      if (this.nresponses == 1)
      {
        int i1 = this.key.verify(paramMessage, paramArrayOfByte, this.lastTSIG);
        if (i1 == 0)
        {
          byte[] arrayOfByte2 = localTSIGRecord.getSignature();
          DNSOutput localDNSOutput3 = new DNSOutput();
          localDNSOutput3.writeU16(arrayOfByte2.length);
          this.verifier.update(localDNSOutput3.toByteArray());
          this.verifier.update(arrayOfByte2);
        }
        this.lastTSIG = localTSIGRecord;
        k = i1;
      }
      while (true)
      {
        while (true)
        {
          while (true)
          {
            int i;
            int j;
            return k;
            if (localTSIGRecord != null)
              paramMessage.getHeader().decCount(3);
            byte[] arrayOfByte1 = paramMessage.getHeader().toWire();
            if (localTSIGRecord != null)
              paramMessage.getHeader().incCount(3);
            this.verifier.update(arrayOfByte1);
            if (localTSIGRecord == null)
              i = paramArrayOfByte.length - arrayOfByte1.length;
            while (true)
            {
              while (true)
              {
                this.verifier.update(paramArrayOfByte, arrayOfByte1.length, i);
                if (localTSIGRecord == null)
                  break label258;
                this.lastsigned = this.nresponses;
                this.lastTSIG = localTSIGRecord;
                if ((localTSIGRecord.getName().equals(TSIG.access$2(this.key))) && (localTSIGRecord.getAlgorithm().equals(TSIG.access$3(this.key))))
                  break label308;
                if (Options.check("verbose"))
                  System.err.println("BADKEY failure");
                paramMessage.tsigState = 4;
                k = 17;
              }
              i = paramMessage.tsigstart - arrayOfByte1.length;
            }
            if (this.nresponses - this.lastsigned >= 100)
              label258: j = 1;
            while (true)
            {
              while (true)
              {
                if (j == 0)
                  break label297;
                paramMessage.tsigState = 4;
                k = 1;
              }
              j = 0;
            }
            label297: paramMessage.tsigState = 2;
            k = 0;
          }
          label308: DNSOutput localDNSOutput1 = new DNSOutput();
          long l1 = localTSIGRecord.getTimeSigned().getTime() / 1000L;
          int l = (int)(l1 >> 32);
          long l2 = l1 & 0xFFFFFFFF;
          localDNSOutput1.writeU16(l);
          localDNSOutput1.writeU32(l2);
          localDNSOutput1.writeU16(localTSIGRecord.getFudge());
          this.verifier.update(localDNSOutput1.toByteArray());
          if (this.verifier.verify(localTSIGRecord.getSignature()))
            break;
          if (Options.check("verbose"))
            System.err.println("BADSIG failure");
          k = 16;
        }
        this.verifier.clear();
        DNSOutput localDNSOutput2 = new DNSOutput();
        localDNSOutput2.writeU16(localTSIGRecord.getSignature().length);
        this.verifier.update(localDNSOutput2.toByteArray());
        this.verifier.update(localTSIGRecord.getSignature());
        k = 0;
      }
    }
  }
}